package com.wash.car.web.config;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.pmo.boot.common.BizException;
import com.pmo.boot.common.api.ResultCommonEnum;
import com.wash.car.web.config.context.UserContext;
import com.wash.car.web.config.context.UserInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


@Slf4j
@Configuration
public class SafetyConfiguration {

    private static final String ORIGINS[] = new String[]{"GET", "POST", "PUT", "DELETE", "OPTIONS"};


    @Bean
    public WebMvcConfigurer safetyConfigurer() {
        return new WebMvcConfigurer() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("/**")
                        .allowedOrigins(new String[]{"*"})
                        .allowedHeaders("*")
                        .allowCredentials(true)
                        .allowedMethods(ORIGINS).maxAge(3600);
            }

            @Override
            public void addInterceptors(InterceptorRegistry registry) {
                registry.addInterceptor(new AdminLoginHandlerInterceptor()).addPathPatterns("/admin/**")  //拦截
                        .excludePathPatterns("/", "/applets/login", "/admin/login", "/login.html", "/doc.html", "/favicon.ico")    //排除
                        .excludePathPatterns("/anon/**", "/health").excludePathPatterns("/swagger-resources/**", "/webjars/**", "/v2/**", "/doc.html/**", "/error");


                registry.addInterceptor(new AppletsLoginHandlerInterceptor()).addPathPatterns("/applets/**")  //拦截
                        .excludePathPatterns("/", "/applets/login", "/admin/login", "/login.html", "/doc.html", "/favicon.ico")    //排除
                        .excludePathPatterns("/anon/**", "/health").excludePathPatterns("/swagger-resources/**", "/webjars/**", "/v2/**", "/doc.html/**", "/error");

            }

            @Override
            public void addResourceHandlers(ResourceHandlerRegistry registry) {
                registry.addResourceHandler("doc.html").addResourceLocations("classpath:/META-INF/resources/");
                registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
            }
        };
    }


    class AdminLoginHandlerInterceptor implements HandlerInterceptor {
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
            response.setHeader("Access-Control-Allow-Origin", "*");
            response.setHeader("Access-Control-Allow-Credentials", "true");
            response.setHeader("Access-Control-Allow-Methods", "GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS");
            response.setHeader("Access-Control-Max-Age", "3600");
            response.setHeader("Access-Control-Allow-Headers", "*");
            if (HttpMethod.OPTIONS.toString().equals(request.getMethod())) {
                response.setStatus(HttpStatus.NO_CONTENT.value());
                return false;
            }
            String token = request.getHeader("token");
            if (StrUtil.isBlank(token)) {
                throw BizException.error(ResultCommonEnum.UNAUTHORIZED.getCode(), "token 不能为空");
            }
            UserInfo userInfo = CacheConfiguration.get(token);
            if (ObjectUtil.isEmpty(userInfo)) {
                throw BizException.error(ResultCommonEnum.UNAUTHORIZED.getCode(), "token 已失效");
            }
            if (userInfo.getIsAdmin() != 1) {
                throw BizException.error(ResultCommonEnum.UNAUTHORIZED.getCode(), "你没有该操作权限！");
            }
            UserContext.add(userInfo);
            return true;
        }

        @Override
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
            UserContext.clear();
        }
    }


    class AppletsLoginHandlerInterceptor implements HandlerInterceptor {
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
            String token = request.getHeader("token");
            if (StrUtil.isBlank(token)) {
                throw BizException.error(ResultCommonEnum.UNAUTHORIZED.getCode(), "token 不能为空");
            }
            UserInfo userInfo = CacheConfiguration.get(token);
            if (ObjectUtil.isEmpty(userInfo)) {
                log.error("登录信息token={}不存在", token);
                throw BizException.error(ResultCommonEnum.UNAUTHORIZED.getCode(), "token 已失效");
            }
            UserContext.add(userInfo);
            return true;
        }


        @Override
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
            UserContext.clear();
        }
    }


}
